/*
 * Copyright 2011-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sabayframework.util;

public final class Hash {

	/*
	 * See http://burtleburtle.net/bob/hash/integer.html
	 * or http://www.concentric.net/~ttwang/tech/inthash.htm
	 * */
	public static int intHash(int a){
	    a -= (a<<6);
	    a ^= (a>>>17);
	    a -= (a<<9);
	    a ^= (a<<4);
	    a -= (a<<3);
	    a ^= (a<<10);
	    a ^= (a>>>15);
	    return a;
	}
	/*
	 * http://www.concentric.net/~ttwang/tech/inthash.htm
	 * */
	public static long longHash(long key)
	{
	  key = (~key) + (key << 21); // key = (key << 21) - key - 1;
	  key ^= (key >>> 24);
	  key = (key + (key << 3)) + (key << 8); // key * 265
	  key ^= (key >>> 14);
	  key = (key + (key << 2)) + (key << 4); // key * 21
	  key ^= (key >>> 28);
	  key += (key << 31);
	  return key;
	}
	
	/*
	 * http://www.concentric.net/~ttwang/tech/inthash.htm
	 * */
	public static int intHash(long key)
	{
	  key = (~key) + (key << 18); // key = (key << 18) - key - 1;
	  key ^= (key >>> 31);
	  key = key * 21; // key = (key + (key << 2)) + (key << 4);
	  key ^= (key >>> 11);
	  key += (key << 6);
	  key ^= (key >>> 22);
	  return (int) key;
	}

	/*
	 * See http://www.partow.net/programming/hashfunctions/
	 * */
	public static long longHash(String str)
	   {
	      long hash = 0xAAAAAAAA;
	      for(int i = 0; i < str.length(); i++)
	      {
	         if ((i & 1) == 0)
	         {
	            hash ^= ((hash << 7) ^ str.charAt(i) * (hash >> 3));
	         }
	         else
	         {
	            hash ^= (~((hash << 11) + str.charAt(i) ^ (hash >> 5)));
	         }
	      }
	      return hash;
	   }

}
